package com.xb.loan.cashier.biz.service.impl;

import com.xb.loan.cashier.biz.dao.CashierChargeOrderDao;
import com.xb.loan.cashier.biz.dao.bean.CashierChargeOrder;
import com.xb.loan.cashier.biz.service.CashierChargeOrderService;
import com.xb.loan.cashier.biz.util.Configure;
import com.xb.loan.cashier.service.constant.ICashierEnumConst;
import com.xb.loan.encryptor.crypt.Encryptor;
import com.xb.loan.encryptor.crypt.EncryptorManager;
import com.xb.loan.util.DateHelper;
import com.xb.loan.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.dubbo.common.utils.CollectionUtils;

import java.text.DecimalFormat;
import java.text.ParseException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;



@Service("cashierChargeOrderService")
public class CashierChargeOrderServiceImpl implements CashierChargeOrderService {
    
    private static final Logger logger = LoggerFactory.getLogger(CashierChargeOrderServiceImpl.class);
    
    private DecimalFormat df = new DecimalFormat("#0.00");

    @Autowired
    private CashierChargeOrderDao cashierChargeOrderDao;
    
    @Override
    public int addOrder(CashierChargeOrder cco) {
        return cashierChargeOrderDao.addOrder(cco);
    }

    @Override
    public int getCountByField(String orderId, String userId, String partnerId, String platId) {
        Map<String, String> params = new HashMap<String, String>();
        params.put("orderId", orderId);
        params.put("userId", userId);
        params.put("partnerId", partnerId);
        params.put("platId", platId);
        return cashierChargeOrderDao.getCountByField(params);
    }

    @Override
    public int updateByOrderId(String platId, String partnerId, String orderId, String tradeTime, int status, String channelOrderId, String errorCode,
                               String errorMsg) {
        Date date = null;
        if (StringUtils.isNotEmpty(tradeTime)) {
            try {
                date = DateHelper.convertToDate(null, tradeTime);
            } catch (ParseException e) {
                logger.error(e.getMessage(),e);
            }
        }
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("orderId", orderId);
        params.put("partnerId", partnerId);
        params.put("platId", platId);
        params.put("tradeTime", date);
        params.put("finishTime", new Date());
        params.put("status", status);
        params.put("channelOrderId", channelOrderId);
        params.put("errorCode", errorCode);
        params.put("errorMsg", errorMsg);
        return cashierChargeOrderDao.updateByOrderId(params);
    }

    @Override
    public int queryStatus(String orderId, String partnerId, String platId) {
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("orderId", orderId);
        params.put("partnerId", partnerId);
        params.put("platId", platId);
        return cashierChargeOrderDao.queryStatus(params);
    }

    @Override
    public List<CashierChargeOrder> queryByStatus(int minute, int limit, int start) {
        Date dateTime = DateHelper.getBeforeMinute(new Date(), -minute);
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("dateTime", dateTime);
        params.put("limit", limit);
        params.put("start", start);
        return cashierChargeOrderDao.queryByStatus(params);
    }

    @Override
    public int updatePushStatusByOrderId(String platId, String partnerId, String orderId, int sendStatus) {
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("orderId", orderId);
        params.put("partnerId", partnerId);
        params.put("platId", platId);
        params.put("pushTime", new Date());
        params.put("pushStatus", sendStatus);
        return cashierChargeOrderDao.updatePushStatusByOrderId(params);
    }

    @Override
    public List<CashierChargeOrder> queryByPushStatus(int minute, int limit, int start) {
        Date dateTime = DateHelper.getBeforeMinute(new Date(), -minute);
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("dateTime", dateTime);
        params.put("limit", limit);
        params.put("start", start);
        return cashierChargeOrderDao.queryByPushStatus(params);
    }

    @Override
    public String encrypt(CashierChargeOrder cashierChargeOrder) {
        logger.info("encrypt money="+cashierChargeOrder.getMoney()+",platId="+cashierChargeOrder.getPlatId()+",userId="+cashierChargeOrder.getUserId()+",orderId="+cashierChargeOrder.getOrderId());
        Encryptor encrytor = EncryptorManager.getEncryptor("partner");
        String cashierId = Configure.getStringValue("encrypt.cashier.id");
        StringBuffer msg = new StringBuffer();
        String split = ICashierEnumConst.EncryptStrCentor.COMMON.getCode();
        msg.append(cashierChargeOrder.getOrderId()).append(split);
        msg.append(cashierChargeOrder.getPlatId()).append(split);
        msg.append(cashierChargeOrder.getUserId()).append(split);
        msg.append(cashierChargeOrder.getPartnerId()).append(split);
        msg.append(df.format(cashierChargeOrder.getMoney())).append(split);
        msg.append(convertStatus(cashierChargeOrder.getStatus()));
        logger.info("encrypt signContent="+msg);
        String encodeStr = encrytor.encrypt(cashierId, null, msg.toString());
        logger.info("encrypt encodeStr="+encodeStr);
        return encodeStr;
    }

    @Override
    public String convertStatus(int status) {
        String state = "";
        if (ICashierEnumConst.CashierChargeStatus.SUCCESS.getStatus()==status) {
            state = ICashierEnumConst.CashierChargeReturnStatus.SUCCESS.getStatus()+"";
        }else if (ICashierEnumConst.CashierChargeStatus.FAIL.getStatus()==status) {
            state = ICashierEnumConst.CashierChargeReturnStatus.FAIL.getStatus()+"";
        }
        return state;
    }

    @Override
    public int queryPushStatus(String orderId, String partnerId, String platId) {
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("orderId", orderId);
        params.put("partnerId", partnerId);
        params.put("platId", platId);
        Integer in = cashierChargeOrderDao.queryPushStatus(params);
        return in!=null?in:0;
    }

    @Override
    public boolean validate(double money, String platId, String userId, String orderId, String partnerId, String sign) {
        logger.info("validate money="+money+",platId="+platId+",userId="+userId+",orderId="+orderId+",sign="+sign);
        String split = ICashierEnumConst.EncryptStrCentor.COMMON.getCode();
        StringBuffer msg = new StringBuffer();
        msg.append(df.format(money)).append(split);
        msg.append(platId).append(split);
        msg.append(userId).append(split);
        msg.append(orderId).append(split);
        msg.append(partnerId);
        logger.info("validate signContent="+msg);
        Encryptor encrytor = EncryptorManager.getEncryptor("partner");
        String encryptedId = Configure.getStringValue("encrypt.cashier.id");
        boolean result = encrytor.encryptValidate(encryptedId, null, msg.toString(), sign);
        logger.info("validate "+result);
        return result;
    }

    @Override
    public int queryCountByAccountDayPlat(String accountDayPlat) {
        return cashierChargeOrderDao.queryCountByAccountDayPlat(accountDayPlat);
    }

    @Override
    public int queryAccountCount(String accountDayPlat) {
        return cashierChargeOrderDao.queryAccountCount(accountDayPlat);
    }

    @Override
    public List<CashierChargeOrder> queryAccountByPage(String accountDayPlat, int start, int limit) {
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("accountDayPlat", accountDayPlat);
        params.put("start", start);
        params.put("limit", limit);
        return cashierChargeOrderDao.queryAccountByPage(params);
    }

    @Override
    public List<CashierChargeOrder> selectThirdLessData(String day, String accountId, int pageNo, int pageSize) {
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("day", day);
        params.put("accountId", accountId);
        params.put("from", (pageNo-1)*pageSize);
        params.put("size", pageSize);
        return cashierChargeOrderDao.selectThirdLessData(params);
    }

    @Override
    public List<CashierChargeOrder> selectAccountNonDatas(String day, String accountId, int pageNo, int pageSize) {
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("day", day);
        params.put("accountId", accountId);
        params.put("from", (pageNo-1)*pageSize);
        params.put("size", pageSize);
        return cashierChargeOrderDao.selectAccountNonDatas(params);
    }

    @Override
    public List<CashierChargeOrder> selectByOrderIds(List<String> orderIds) {
        if(CollectionUtils.isEmpty(orderIds)){
            return null;
        }
        return cashierChargeOrderDao.selectByOrderIds(orderIds);
    }

    @Override
    public int updateThirdAccountTime(List<String> orderIds, String day) {
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("orderIds", orderIds);
        params.put("accountDay", day);
        return cashierChargeOrderDao.updateThirdAccountTime(params);
    }

    @Override
    public CashierChargeOrder queryByOrderId(String orderId) {
        return cashierChargeOrderDao.queryByOrderId(orderId);
    }

    @Override
    public int updatePushCount(String orderId, int pushStatus, int maxPushCount) {
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("orderId", orderId);
        params.put("pushStatus", pushStatus);
        params.put("maxPushCount", maxPushCount);
        return cashierChargeOrderDao.updatePushCount(params);
    }
    
    @Override
    public int updateAccountStatus(String accountId, String orderId, int accountStatus, String accountDay) {
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("accountId", accountId);
        params.put("orderId", orderId);
        params.put("accountStatus", accountStatus);
        params.put("accountDay", accountDay);
        return cashierChargeOrderDao.updateAccountStatus(params);
    }

    @Override
    public int queryPushCount(String orderId) {
        return cashierChargeOrderDao.queryPushCount(orderId);
    }

}
